import { useContext, useState } from 'react';
import { Row, Col, Button, message } from 'antd';
import { omitBy, isNil } from 'lodash';
import ProForm from '@ant-design/pro-form';
import ActionPersonItem from '../ActionPersonItem/index';
import { required, validImageWhenSubmit } from '@/utils/form/rules';
import { ProColumnType } from '@ant-design/pro-table';
import styles from './index.scss';
import { UserAddState } from './interface';
import { useRequest } from 'ahooks';
import { batchAddUser, fetchUserCateInfo } from '@/service/personnelEntry';
import { addUser } from '@/service/personnelEntry';
import { toPersonnelEntry } from '../..';
import { UserCateInfo } from '../../interface';
import { PageTabActionContext } from '@/layouts/index';
import useAutoInjectCateInfo from '../../hooks/useAutoInjectCateInfo';
import { history } from 'umi';

const to_number_keys = [
    'no_type',
    'corps_id',
    'serve_status',
    'sex',
    'age',
    'user_id',
    'id',
];

const rawColumns: ProColumnType<UserAddState>[] = [
    {
        title: '用户名',
        valueType: 'text',
        key: 'username',
        formItemProps: {
            rules: [required('请输入用户名')],
        },
    },
    { title: '年龄', valueType: 'text', key: 'age' },
    {
        title: '性别',
        valueType: 'select',
        key: 'sex',
        valueEnum: {
            0: '未知',
            1: '女',
            2: '男',
        },
    },
    {
        title: '是否服役',
        key: 'serve_status',
        valueType: 'select',
        formItemProps: {
            rules: [required('请输入是否服役')],
        },
        valueEnum: {},
    },
    {
        title: '所属军队',
        key: 'army_id',
        valueType: 'cascader',
        formItemProps: {
            rules: [required('请输入所属军队')],
        },
    },
    {
        title: '兵种',
        key: 'corps_id',
        valueType: 'select',
        formItemProps: {
            rules: [required('请输入兵种')],
        },
        valueEnum: {
            1: '火箭兵',
        },
    },
    {
        title: '证件类型',
        key: 'no_type',
        valueType: 'select',
        formItemProps: {
            rules: [required('请输入证件类型')],
        },
        valueEnum: {},
    },
    {
        title: '证件编号',
        key: 'no',
        formItemProps: {
            rules: [required('请输入证件编码')],
        },
    },
    {
        title: '地址',
        key: 'address',
        dataIndex: 'address',
    },
];

/** 将表单转换为请求可用 */
export function transformToSubmitData(values: any[]): any {
    return values.map((item: any) => {
        const { avatar } = item;

        const v = {
            ...omitBy(item, (val) => isNil(val) || val === ''),
            ...(avatar?.[0]?.response ? { avatar: avatar?.[0].response } : {}),
        };

        return Object.keys(v).reduce((result, i) => {
            if (to_number_keys.includes(i)) {
                // @ts-ignore
                result[i] = Number(result[i]);
            }
            if (i === 'army_id') {
                // @ts-ignore
                result[i] = result[i][2];
            }
            return result;
        }, v);
    });
}

/** 将请求下来的数据转换为表单可用数据 */
export function transformToFormData(values: any[]): any[] {
    return values.map((item: any) => {
        return {
            ...item,
            ...(item.avatar
                ? { avatar: [{ response: item.avatar, url: item.avatar }] }
                : {}),
            ...(item.army_id ? { army_id: [item.army_id] } : {}),
        };
    });
}

/**
 * 展开多级表单值
 */
const flatDeepCateInfo = (d: UserCateInfo['army']): UserCateInfo['army'] => {
    if (!d || d.length === 0) return [];
    // @ts-ignore
    return d.map((item) => [item, flatDeepCateInfo(item.child)]).flat(Infinity);
};

/**
 * 寻找多级表单值
 */
export function findCascaderValue(data: UserCateInfo, target: string) {
    const datas = flatDeepCateInfo(data.army);

    let pid = target;
    let i;
    let result = [pid];
    while ((i = datas.find((item) => item.id === pid))) {
        result.unshift(i.pid);
        pid = i.pid;
    }
    result.shift();
    return result;
}

export default function AddPerson() {
    const [form] = ProForm.useForm();
    const [keyList, setKeyList] = useState<number[]>([0]);
    const { removeCurrentTab } = useContext(PageTabActionContext);

    /** 修改提交 */
    const { loading, run: submitUsers } = useRequest(async (rawValues) => {
        const values = transformToSubmitData(Object.values(rawValues));

        let res;
        if (values.length > 1) {
            res = await batchAddUser(values);
        } else {
            res = await addUser(values[0]);
        }

        if (res.code !== 200) {
            message.error(res.msg || '服务器异常，请稍后重试');
            return;
        }
        message.success('新增成功');
        removeCurrentTab();
        history.push('/personnelEntry');
    });

    const { columns } = useAutoInjectCateInfo(rawColumns);

    return (
        <div style={{ position: 'relative' }}>
            <ProForm
                form={form}
                submitter={false}
                onFinish={async (values) => {
                    submitUsers(values);
                }}
            >
                <Row gutter={[0, 16]}>
                    {keyList.map((item) => (
                        <Col span={24} className={styles.personItem}>
                            <ActionPersonItem
                                form={form}
                                prefix={item}
                                onReset={() => {
                                    form.resetFields([item]);
                                }}
                                onDelete={() => {
                                    if (keyList.length === 1) return;
                                    form.resetFields([item]);
                                    setKeyList(
                                        keyList.filter((i) => i !== item),
                                    );
                                }}
                                columns={columns}
                                uploadProps={{
                                    rules: [validImageWhenSubmit('请上传头像')],
                                }}
                            />
                        </Col>
                    ))}
                </Row>
            </ProForm>

            <Row justify="space-between" className={styles.controller}>
                <Col>
                    <Button
                        type="primary"
                        onClick={() => {
                            setKeyList([
                                ...keyList,
                                (keyList[keyList.length - 1] || 0) + 1,
                            ]);
                        }}
                    >
                        新增
                    </Button>
                </Col>
                <Col>
                    <Button
                        onClick={() => {
                            removeCurrentTab();
                            toPersonnelEntry();
                        }}
                    >
                        取消
                    </Button>
                    <Button onClick={() => form.submit()}>提交</Button>
                </Col>
            </Row>
        </div>
    );
}
